package com.frank.oj.manager;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.frank.model.entity.problem.Tag;
import com.frank.model.entity.problem.TagClassification;
import com.frank.oj.model.vo.ProblemTagVO;
import com.frank.oj.service.problem.TagClassificationService;
import com.frank.oj.service.problem.TagService;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author frank
 * @Date 2024/3/22
 */
@Component
public class CommonManager {
    @Resource
    private TagClassificationService tagClassificationService;
    @Resource
    private TagService tagService;

    public List<ProblemTagVO> getProblemTagsAndClassification(String oj) {
        oj = oj.toUpperCase();

        List<ProblemTagVO> problemTagList = new ArrayList<>();
        List<TagClassification> tagClassifications = null;
        List<Tag> tagList = null;

        if ("All".equals(oj)) {
            tagClassifications = tagClassificationService.list();

            LambdaQueryWrapper<Tag> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.isNull(Tag::getGid);
            tagList = tagService.list(queryWrapper);
        } else {
            LambdaQueryWrapper<TagClassification> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(TagClassification::getOj, oj)
                    .orderByAsc(TagClassification::getRank);
            tagClassifications = tagClassificationService.list(queryWrapper);

            LambdaQueryWrapper<Tag> tagLambdaQueryWrapper = new LambdaQueryWrapper<>();
            tagLambdaQueryWrapper.isNull(Tag::getGid) // 非团队标签
                    .eq(Tag::getOj, oj);
            tagList = tagService.list(tagLambdaQueryWrapper);
        }

        if (CollectionUtils.isEmpty(tagClassifications)){
            ProblemTagVO problemTagVO = new ProblemTagVO();
            problemTagVO.setTagList(tagList);
            problemTagList.add(problemTagVO);
        }else {
            for (TagClassification classification : tagClassifications) {

                ProblemTagVO problemTagVO = new ProblemTagVO();
                problemTagVO.setClassification(classification);

                ArrayList<Tag> tags = new ArrayList<>();
                if (!CollectionUtils.isEmpty(tagList)){
                    tagList.forEach(tag -> {
                        if (classification.getId().equals(tag.getTcid())){
                            tags.add(tag);
                        }
                    });
                }
                problemTagVO.setTagList(tags);
                problemTagList.add(problemTagVO);
            }
            if (!tagList.isEmpty()){
                ProblemTagVO problemTagVO = new ProblemTagVO();
                problemTagVO.setTagList(tagList);
                problemTagList.add(problemTagVO);
            }
        }
        if ("ALL".equals(oj)){
            problemTagList.sort(problemTagVoComparator);
        }
        return problemTagList;
    }

    /**
     *    根据分类排序
     */
    private final Comparator<ProblemTagVO> problemTagVoComparator = (p1, p2) -> {
        if (p1 == null) {
            return 1;
        }
        if (p2 == null) {
            return 1;
        }
        if (p1.getClassification() == null) {
            return 1;
        }
        if (p2.getClassification() == null) {
            return -1;
        }
        TagClassification p1Classification = p1.getClassification();
        TagClassification p2Classification = p2.getClassification();
        if (Objects.equals(p1Classification.getOj(), p2Classification.getOj())) {
            return p1Classification.getRank().compareTo(p2Classification.getRank());
        } else {
            if ("ME".equals(p1Classification.getOj())) {
                return -1;
            } else if ("ME".equals(p2Classification.getOj())) {
                return 1;
            } else {
                return p1Classification.getOj().compareTo(p2Classification.getOj());
            }
        }
    };
}
